package com.future.future.movie.exception;

import com.future.future.commons.response.ErrorCode;
import com.future.future.commons.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: shinan
 * @Version: 1.8
 * @create: 2021/1/18 20:01
 * @Description: TODO
 */
@RestControllerAdvice(basePackages = "com.future.future.movie.controller")
@Slf4j
public class MovieExceptionController {

    /**
     * 用来处理参数格式校验错误抛出的异常
     *
     * @param e 参数格式校验错误异常
     * @return 返回信息
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R handleValidException(MethodArgumentNotValidException e) {

        //1. 打印错误信息日志
        log.error("数据校验出现问题:{},异常类型:{}", e.getMessage(), e.getClass());

        //2. 获取校验的结果
        BindingResult bindingResult = e.getBindingResult();

        //3. 获取bean的哪些属性校验出错的
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();

        //4. 将这些属性的错误信息封装到map中向前端返回
        Map<String, String> errors = new HashMap<>();
        fieldErrors.forEach((fieldError) -> {
            //校验错误属性
            String field = fieldError.getField();
            //校验错误提示信息
            String defaultMessage = fieldError.getDefaultMessage();
            errors.put(field, defaultMessage);
        });

        //5. 错误状态码
        Integer code = ErrorCode.VALID_EXCEPTION.getCode();
        //6. 错误信息
        String message = ErrorCode.VALID_EXCEPTION.getMessage();

        return R.error(code, message).put("errorMessage", errors);
    }

    /**
     * 处理全局异常
     * 使用@ExceptionHandler这个注解来标记该方法处理那些类型的异常
     *
     * @param throwable The {@code Throwable} class is the superclass of all errors
     *                  and exceptions in the Java language
     * @return 向页面返回结果
     */
    @ExceptionHandler(value = Throwable.class)
    public R handleException(Throwable throwable) {

        //1. 打印错误信息日志
        log.error("错误:", throwable);

        Integer code = ErrorCode.UN_KNOW_EXCEPTION.getCode();
        String message = ErrorCode.UN_KNOW_EXCEPTION.getMessage();

        return R.error(code, message);
    }
}